package com.example.controller;

import com.example.bean.Product;
import com.example.config.WechatUrlConfig;
import com.example.config.WxpayConfig;
import com.example.utils.*;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 也是
 * @Date 2023/3/29
 */
@RestController
@RequestMapping("/wechatpay")
public class PayController {
	@PostMapping("/doPay")
	public Map<String, Object> wxPay(String openid, Integer type, Product product) throws JsonProcessingException, IOException {
		type =2;
		product = new Product();
		product.setSubject("报名费");
		product.setOutTradeNo("99818817171827375589389393838939");
		product.setTotalFee("10");
		Map<String, Object> map = new HashMap();
		// 支付的产品（小程序或者公众号，主要需要和微信支付绑定哦）
		map.put("appid", WxpayConfig.app_id);
		// 支付的商户号
//		map.put("mchid", WxpayConfig.mch_id);
		map.put("mchid", WxpayConfig.mch_id);
		//临时写死配置
		map.put("description", product.getSubject());
		map.put("out_trade_no", product.getOutTradeNo());
		map.put("notify_url", WxpayConfig.notify_order_url);

		Map<String, Object> amount = new HashMap();
		//订单金额 单位分
		amount.put("total", Integer.parseInt(product.getTotalFee()) * 100);
		amount.put("currency", "CNY");
		map.put("amount", amount);
		// 设置小程序所需的opendi
		Map<String, Object> payermap = new HashMap();
		if (type==1){
			payermap.put("openid", openid);
			map.put("payer", payermap);
		}

		ObjectMapper objectMapper = new ObjectMapper();
		String body = objectMapper.writeValueAsString(map);

		Map<String, Object> stringObjectMap = null;
		HashMap<String, Object> dataMap = null;
		try {
			switch (type) {
				case 1:
					stringObjectMap = HttpUtils.doPostWexin(WechatUrlConfig.JSAPIURL, body);
					dataMap = WeixinchatPayUtils.getTokenJSAPI(WxpayConfig.app_id, String.valueOf(stringObjectMap.get("prepay_id")));
					break;
				default:
					stringObjectMap = HttpUtils.doPostWexin(WechatUrlConfig.APPURL, body);
					dataMap = WeixinchatPayUtils.getTokenApp(WxpayConfig.app_id, String.valueOf(stringObjectMap.get("prepay_id")));
					break;
			}
			return dataMap;
		} catch (Exception ex) {
		}
		return null;
	}

	@PostMapping("pay/callback")
	public Map orderPayCallback(@RequestBody Map body, HttpServletRequest request) {
//		log.info("1----------->微信支付回调开始");
		Map<String, Object> result = new HashMap();
		//1：获取微信支付回调的获取签名信息
		String timestamp = request.getHeader("Wechatpay-Timestamp");
		String nonce = request.getHeader("Wechatpay-Nonce");
		ObjectMapper objectMapper = new ObjectMapper();
		try {
			// 2: 开始解析报文体
			String data = objectMapper.writeValueAsString(body);
			String message = timestamp + "\n" + nonce + "\n" + data + "\n";
			//3：获取应答签名
			String sign = request.getHeader("Wechatpay-Signature");
			//4：获取平台对应的证书
			String serialNo = request.getHeader("Wechatpay-Serial");
			if (!WxpayConfig.certificateMap.containsKey(serialNo)) {
				WxpayConfig.certificateMap = WechatPayUtils.refreshCertificate();
			}
			X509Certificate x509Certificate = WxpayConfig.certificateMap.get(serialNo);
			if (!WechatPayUtils.verify(x509Certificate, message.getBytes(), sign)) {
				throw new IllegalArgumentException("微信支付签名验证失败:" + message);
			}
			//    log.info("签名验证成功");
			Map<String, String> resource = (Map) body.get("resource");
			// 5：回调报文解密
			AesUtil aesUtil = new AesUtil(WxpayConfig.v3Key.getBytes());
			//解密后json字符串
			String decryptToString = aesUtil.decryptToString(
					resource.get("associated_data").getBytes(),
					resource.get("nonce").getBytes(),
					resource.get("ciphertext"));
			// log.info("2------------->decryptToString====>{}", decryptToString);

			//6：获取微信支付返回的信息
			Map<String, Object> jsonData = objectMapper.readValue(decryptToString, Map.class);
			//7: 支付状态的判断 如果是success就代表支付成功
			if ("SUCCESS".equals(jsonData.get("trade_state"))) {
				// 8：获取支付的交易单号，流水号，和附属参数
				String out_trade_no = jsonData.get("out_trade_no").toString();
				String transaction_id = jsonData.get("transaction_id").toString();
				String attach = jsonData.get("attach").toString();
				//TODO 根据订单号查询支付状态，如果未支付，更新支付状态 为已支付
				//   log.info("3----------->微信支付成功,支付流水号是：{},附属参数是：{}", out_trade_no, attach);
				//   log.info("4----------->微信支付成功,支付流水号是：{}", transaction_id);
				// 转换附属参数
				HashMap<String, Object> map = JsonUtil.string2Obj(attach, HashMap.class);
				// 9：保存用户支付信息

			}
			result.put("code", "SUCCESS");
			result.put("message", "成功");
		} catch (Exception e) {
			result.put("code", "fail");
			result.put("message", "系统错误");
			e.printStackTrace();
		}
		return result;


	}


}
